package dawn.core.dispatch;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class SingleListenerDispathcer<K, E> implements IDispatcher<K, E> {

	Map<K, Invoker<E>> listenerMap = new HashMap<K, Invoker<E>>();

	Map<K, List<IFilter>> filterMap = new HashMap<K, List<IFilter>>();

	@Override
	public void dispatch(K type, E E) {

		// for
		List<IFilter> filters = filterMap.get(type);
		if (filters != null) {
			for (IFilter filter : filters) {
				filter.before(null, null, null);
			}
		}

		Invoker<E> invoker = listenerMap.get(type);
		if (invoker != null) {
			try {
				invoker.handle(E);
			} catch (Exception e) {
				if (filters != null) {
					for (IFilter filter : filters) {
						filter.error(null, null, null);
					}
				}
				e.printStackTrace();
			}
		}

		if (filters != null) {
			for (IFilter filter : filters) {
				filter.after(null, null, null, null);
			}

		}
	}

	public Object invoker(K type, E E) {

		// for
		List<IFilter> filters = filterMap.get(type);
		if (filters != null) {
			for (IFilter filter : filters) {
				filter.before(null, null, null);
			}
		}

		Object ret = null;

		Invoker<E> invoker = listenerMap.get(type);
		if (invoker != null) {
			try {
				ret = invoker.handle(E);
			} catch (Exception e) {
				if (filters != null) {
					for (IFilter filter : filters) {
						filter.error(null, null, null);
					}
				}
				e.printStackTrace();
			}
		}

		if (filters != null) {
			for (IFilter filter : filters) {
				filter.after(null, null, null, null);
			}

		}

		return ret;
	}

	@Override
	public void addListener(K type, Invoker<E> listener) {

		listenerMap.put(type, listener);
	}

	@Override
	public void addFilter(K type, IFilter filter) {
		List<IFilter> list = filterMap.get(type);
		if (list == null) {
			list = new ArrayList<IFilter>();
			filterMap.put(type, list);
		}
		list.add(filter);
	}

}
